﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using DevelopTool.Bll.DbBlls;
using DevelopTool.Common;
using DevelopTool.Forms.BaseForms;
using DevelopTool.Forms.CommonControls;
using DevelopTool.Forms.CommonForms;
using DevelopTool.Forms.CommonHelpers;
using DevelopTool.Forms.LodingForm;
using DevelopTool.Model;
using DevelopTool.Model.DbModels;
using DevelopTool.SqlAnalyze;
using Sunny.UI;

namespace DevelopTool.Forms.DbForms
{
    /// <summary>
    /// sql分析
    /// </summary>
    public partial class SqlAnalyzeForm : BaseUIPage
    {
        /// <summary>
        /// 结果字典
        /// </summary>
        private readonly Dictionary<string,List<OperateInfo>> resultDic = new Dictionary<string,List<OperateInfo>>();

        /// <summary>
        /// 位置
        /// </summary>
        private int index = 0;

        /// <summary>
        /// 数据库通用操作类
        /// </summary>
        private DbManagerBll dbManagerBll;

        /// <summary>
        /// 数据库连接信息
        /// </summary>
        private DbInfo dbInfo;

        /// <summary>
        ///顶部节点，系统预定义
        /// </summary>
        private TreeNode topTreeNode;

        /// <summary>
        /// TreeView帮助类
        /// </summary>
        private TreeViewHelper treeViewHelper;

        private string sqlText;

        public SqlAnalyzeForm()
        {
            InitializeComponent();
        }

        public SqlAnalyzeForm(string sqlText,DbInfo dbInfo)
        {
            InitializeComponent();

            this.sqlText = sqlText;
            this.dbInfo = dbInfo;
            this.dbManagerBll = new DbManagerBll(dbInfo);


        }

        private void SqlAnalyzeForm_Load(object sender,EventArgs e)
        {



            this.chbShowType.SelectedIndex = 0;

            #region 读取设置

            this.menuItemAlwaysShowColumnWindow.Checked = Setting.SqlAnalyze.AlwaysShowColumnWindow;
            this.menuItemAlwaysShowSqlTextWindow.Checked = Setting.SqlAnalyze.AlwaysShowSqlTextWindow;
            #endregion

            this.codeEditorSqlIn.ContentText = this.sqlText;

            uiSplitContainer1.Panel2Collapsed = true;//默认折叠Sql展示窗口
            uiSplitContainer3.Panel2Collapsed = true;

            this.dbinfoComboBox.DefaultSelectedDbInfo = this.dbInfo;

            if(!string.IsNullOrEmpty(this.codeEditorSqlIn.ContentText))
                SqlAnalyze(this.codeEditorSqlIn.ContentText);
        }


        /// <summary>
        /// sql分析
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSqlAnalyze_Click(object sender,EventArgs e)
        {
            SqlAnalyze(this.codeEditorSqlIn.ContentText);
        }

        private void SqlAnalyze(string sqlText)
        {
            if(string.IsNullOrEmpty(sqlText)) return;

            this.resultDic.Clear();
            this.index = 0;

            this.uiTreeView_Table.Nodes.Clear();
            this.codeEditorSqlResult.ClearContent();
            this.uiListBox_Column.Items.Clear();

            LoadingHelper.ShowLoading("正在分析sql",() =>
            {
                SqlAnalyzeHandle(sqlText);//sql解析

            },this.TopMost);


            if(this.dbInfo != null && this.dbManagerBll != null && this.resultDic.Count > 0)
            {
                LoadingHelper.ShowLoading("正在查询表注释和字段注释",() =>
                {
                    SetComments(this.resultDic);//设置表和字段的注释

                },this.TopMost);
            }

            ShowResult(this.resultDic);
        }


        /// <summary>
        /// sql解析
        /// </summary>
        /// <param name="texts"></param>
        private void SqlAnalyzeHandle(string text)
        {
            #region 替换一些字符，后续可以继续添加替换字符，目前遇到的就这些
            text = text.Replace("！=","<>");
            text = text.Replace("!=","<>");
            text = text.Replace("[","'");
            text = text.Replace("]","'");
            #endregion

            string[] texts = text.Split("--------------------------------------------------------------------------------",true);

            foreach(string blockText in texts)
            {
                string sql = string.Empty;
                string timestamp = string.Empty;
                string elapsedTime = string.Empty;

                try
                {
                    if(string.IsNullOrWhiteSpace(blockText)) continue;

                    //截取-执行时间
                    timestamp = Regex.Match(blockText,@"Timestamp: (\d{4}[/-]\d{1,2}[/-]\d{1,2} \d{1,2}:\d{1,2}:\d{1,2})")?.Groups[1].Value?.Trim();

                    //截取-执行耗时
                    elapsedTime = Regex.Match(blockText,@"Elapsed time: (\d+\.\d+)")?.Groups[1].Value?.Trim();

                    //替换多余的字符
                    sql = Regex.Replace(blockText.Replace($"Timestamp: {timestamp}","").Replace($"Elapsed time: {elapsedTime}","").Trim(),@":(\w+)\s*=\s*\[[^]]*\]","");
                    sql = Regex.Replace(sql,@"(\w+)\s*=\s*\[[^]]*\]","");
                    sql = Regex.Replace(sql,@":\d+=''(.*?)''","");
                    sql = Regex.Replace(sql,@":\d+='(.*?)'","");
                    sql = Regex.Replace(sql,@"Logout \([^)]*\): '(.*?)'","");

                    if(string.IsNullOrWhiteSpace(sql)) continue;

                    ProcedureInfo procedureInfo = new Analyzesp().GetResult(sql);//这是核心

                    AddToDic(procedureInfo,sql,timestamp,elapsedTime);

                }
                catch(Exception ex)
                {
                    //记录未能解析的sql
                    ProcedureInfo procedureInfo = new ProcedureInfo
                    {
                        OperateInfos = new List<OperateInfo>
                    {
                        new OperateInfo()
                        {
                            TableName="未能解析的文本",
                            UsageType=UsageType.Unknown,
                            Sql=sql,
                        }
                    }
                    };
                    AddToDic(procedureInfo,sql,timestamp,elapsedTime);
                }

            }
        }



        /// <summary>
        /// 将解析结果添加到字典集合
        /// </summary>
        /// <param name="procedureInfo"></param>
        /// <param name="sql"></param>
        /// <param name="timestamp"></param>
        /// <param name="elapsedTime"></param>
        private void AddToDic(ProcedureInfo procedureInfo,string sql,string timestamp,string elapsedTime)
        {
            foreach(OperateInfo operateInfo in procedureInfo.OperateInfos)
            {
                index++;
                operateInfo.Timestamp = timestamp;
                operateInfo.ElapsedTime = elapsedTime;
                operateInfo.Index = index;
                operateInfo.Sql = sql;

                if(!resultDic.ContainsKey(operateInfo.TableName)) resultDic.Add(operateInfo.TableName,new List<OperateInfo>());

                List<OperateInfo> operateInfos = resultDic[operateInfo.TableName];

                operateInfos.Add(operateInfo);

                resultDic[operateInfo.TableName] = operateInfos;
            }
        }


        /// <summary>
        /// 设置表和字段的注释
        /// </summary>
        /// <param name="data"></param>
        private void SetComments(Dictionary<string,List<OperateInfo>> data)
        {
            var tableNames = data.Select(it => it.Key).ToList();//表名集合

            DataTable tables = new DataTable();
            DataTable columns = new DataTable();

            foreach(string tableName in tableNames)
            {
                var tuple = this.dbManagerBll.GetDatabaseNameAndTableName(tableName);

                //根据表名获取表集合
                if(tables.Rows.Count > 0)
                {
                    string tj = $"TABLE_NAME='{tuple.Item2.ToUpper()}'";
                    if(!string.IsNullOrEmpty(tuple.Item1)) tj += $" AND OWNER='{tuple.Item1.ToUpper()}'";
                    if(tables.Select(tj).Length <= 0)//如果已经查询了表注释那就不再重新获取了
                    {
                        DataTable dataTable = this.dbManagerBll.GetTables(tuple.Item1,tuple.Item2);
                        if(dataTable.Rows.Count > 0)
                            tables.Merge(dataTable);
                    }
                }
                else
                {
                    DataTable dataTable = this.dbManagerBll.GetTables(tuple.Item1,tuple.Item2);
                    if(dataTable.Rows.Count > 0)
                        tables.Merge(dataTable);
                }


                //根据表名获取字段集合
                if(columns.Rows.Count > 0)
                {
                    string tj = $"TABLE_NAME='{tuple.Item2.ToUpper()}'";
                    if(!string.IsNullOrEmpty(tuple.Item1)) tj += $" AND OWNER='{tuple.Item1.ToUpper()}'";
                    if(columns.Select(tj).Length <= 0)
                    {

                        DataTable dataColumns = this.dbManagerBll.GetTableColumns(tuple.Item1,tuple.Item2);
                        if(dataColumns.Rows.Count > 0)
                            columns.Merge(dataColumns);
                    }
                }
                else
                {
                    DataTable dataColumns = this.dbManagerBll.GetTableColumns(tuple.Item1,tuple.Item2);
                    if(dataColumns.Rows.Count > 0)
                        columns.Merge(dataColumns);
                }

            }

            if(tables.Rows.Count <= 0) return;//tables为空有可能识别到的是个视图或者是别的什么，反正不是表。

            List<KeyValuePair<string,List<OperateInfo>>> list = new List<KeyValuePair<string,List<OperateInfo>>>(data);

            foreach(KeyValuePair<string,List<OperateInfo>> kvp in list)
            {
                List<OperateInfo> operateInfos = data[kvp.Key];

                for(int i = 0 ; i < operateInfos.Count ; i++)
                {
                    var tuple = this.dbManagerBll.GetDatabaseNameAndTableName(operateInfos[i].TableName);
                    DataRow[] tableDatas = tables.Select($"TABLE_NAME='{tuple.Item2.ToUpper()}'");
                    if(tableDatas.Length <= 0) continue;

                    operateInfos[i].Comments = tableDatas[0]["COMMENTS"].ToString();//设置表注释

                    for(int j = 0 ; j < operateInfos[i].Columns.Count ; j++)
                    {
                        DataRow[] columnDatas = columns.Select($"COLUMN_NAME='{operateInfos[i].Columns[j].ColumnName.ToUpper()}' and TABLE_NAME='{tableDatas[0]["TABLE_NAME"]}' and OWNER='{tableDatas[0]["OWNER"]}'");
                        if(columnDatas.Length <= 0) continue;

                        operateInfos[i].Columns[j].Comments = columnDatas[0]["COMMENTS"].ToString();//设置字段注释
                    }
                }
                data[kvp.Key] = operateInfos;//重新把对象塞回去~
            }

        }

        #region 展示结果

        /// <summary>
        /// 展示分析结果
        /// </summary>
        /// <param name="data"></param>
        private void ShowResult(Dictionary<string,List<OperateInfo>> data)
        {
            if(this.chbShowType.SelectedIndex == 0)
            {
                this.ShowResultWithTable(data);//按表展示
            }
            else if(this.chbShowType.SelectedIndex == 1)
            {
                this.ShowResultWithUsage(data);//按操作类型展示
            }
            else if(this.chbShowType.SelectedIndex == 2)
            {
                this.ShowResultWithOrder(data);//按执行顺序展示
            }
            else if(this.chbShowType.SelectedIndex == 3)
            {
                this.ShowResultWithElapsedTime(data);//按执行时间展示
            }
        }

        /// <summary>
        /// 按表展示树
        /// </summary>
        private void ShowResultWithTable(Dictionary<string,List<OperateInfo>> data)
        {
            this.topTreeNode = uiTreeView_Table.Nodes.Add("topTreeNode",$"分析结果({data.Values.Count})");

            foreach(var kvp in data)
            {
                //表注释
                string tableComments = string.IsNullOrWhiteSpace(kvp.Value[0].Comments) ? "" : "-" + kvp.Value[0].Comments;

                TreeNode tableNode = this.topTreeNode.Nodes.Add("tableNode",$"{kvp.Key}({kvp.Value.Count}){tableComments}",0);

                //select                
                var usageTypes = kvp.Value.Where(it => it.UsageType == UsageType.Select);
                if(usageTypes.Count() > 0)
                {
                    this.CreateInfoTreeNode("usageNode",usageTypes,tableNode,"查询",1);
                }

                //update                
                usageTypes = kvp.Value.Where(it => it.UsageType == UsageType.Update);
                if(usageTypes.Count() > 0)
                {
                    this.CreateInfoTreeNode("usageNode",usageTypes,tableNode,"更新",4);
                }

                //insert                
                usageTypes = kvp.Value.Where(it => it.UsageType == UsageType.Insert);
                if(usageTypes.Count() > 0)
                {
                    this.CreateInfoTreeNode("usageNode",usageTypes,tableNode,"新增",3);
                }

                //delete                
                usageTypes = kvp.Value.Where(it => it.UsageType == UsageType.Delete);
                if(usageTypes.Count() > 0)
                {
                    this.CreateInfoTreeNode("usageNode",usageTypes,tableNode,"删除",2);
                }

                //Unknown 未知                
                usageTypes = kvp.Value.Where(it => it.UsageType == UsageType.Unknown);
                if(usageTypes.Count() > 0)
                {
                    this.CreateInfoTreeNode("usageNode",usageTypes,tableNode,"未知",6);
                }

                //create                
                usageTypes = kvp.Value.Where(it => it.UsageType == UsageType.Create);
                if(usageTypes.Count() > 0)
                {
                    this.CreateInfoTreeNode("usageNode",usageTypes,tableNode,"建表",1);
                }

                tableNode.Expand();//展开“表”节点
            }
            topTreeNode.Expand();//展开顶级节点
        }


        /// <summary>
        /// 按操作类型展示树
        /// </summary>
        private void ShowResultWithUsage(Dictionary<string,List<OperateInfo>> data)
        {
            this.topTreeNode = uiTreeView_Table.Nodes.Add("topTreeNode",$"分析结果({data.Values.Count})");

            TreeNode selectUsageNode = this.topTreeNode.Nodes.Add("usageNode",$"查询",1);
            TreeNode updateUsageNode = this.topTreeNode.Nodes.Add("usageNode",$"更新",4);
            TreeNode insertUsageNode = this.topTreeNode.Nodes.Add("usageNode",$"新增",3);
            TreeNode deleteUsageNode = this.topTreeNode.Nodes.Add("usageNode",$"删除",2);
            TreeNode unknownUsageNode = this.topTreeNode.Nodes.Add("usageNode",$"未知",6);
            TreeNode createUsageNode = this.topTreeNode.Nodes.Add("usageNode",$"建表",1);

            foreach(var kvp in data)
            {
                //表注释
                string tableComments = string.IsNullOrWhiteSpace(kvp.Value[0].Comments) ? "" : "-" + kvp.Value[0].Comments;

                var usageTypes = kvp.Value.Where(it => it.UsageType == UsageType.Select);
                if(usageTypes.Count() > 0)
                {
                    this.CreateInfoTreeNode("tableNode",usageTypes,selectUsageNode,$"{kvp.Key}({usageTypes.Count()}){tableComments}",0);
                }

                usageTypes = kvp.Value.Where(it => it.UsageType == UsageType.Update);
                if(usageTypes.Count() > 0)
                {
                    this.CreateInfoTreeNode("tableNode",usageTypes,updateUsageNode,$"{kvp.Key}({usageTypes.Count()}){tableComments}",0);
                }

                usageTypes = kvp.Value.Where(it => it.UsageType == UsageType.Insert);
                if(usageTypes.Count() > 0)
                {
                    this.CreateInfoTreeNode("tableNode",usageTypes,insertUsageNode,$"{kvp.Key}({usageTypes.Count()}){tableComments}",0);
                }

                usageTypes = kvp.Value.Where(it => it.UsageType == UsageType.Delete);
                if(usageTypes.Count() > 0)
                {
                    this.CreateInfoTreeNode("tableNode",usageTypes,deleteUsageNode,$"{kvp.Key}({usageTypes.Count()}){tableComments}",0);
                }

                usageTypes = kvp.Value.Where(it => it.UsageType == UsageType.Unknown);
                if(usageTypes.Count() > 0)
                {
                    this.CreateInfoTreeNode("tableNode",usageTypes,unknownUsageNode,$"{kvp.Key}({usageTypes.Count()}){tableComments}",0);
                }

                usageTypes = kvp.Value.Where(it => it.UsageType == UsageType.Create);
                if(usageTypes.Count() > 0)
                {
                    this.CreateInfoTreeNode("tableNode",usageTypes,createUsageNode,$"{kvp.Key}({usageTypes.Count()}){tableComments}",0);
                }
            }


            if(selectUsageNode.Nodes.Count <= 0) selectUsageNode.Remove();
            else selectUsageNode.Text += $"({selectUsageNode.Nodes.Find("infoNode",true).Count()})";

            if(updateUsageNode.Nodes.Count <= 0) updateUsageNode.Remove();
            else updateUsageNode.Text += $"({updateUsageNode.Nodes.Find("infoNode",true).Count()})";

            if(insertUsageNode.Nodes.Count <= 0) insertUsageNode.Remove();
            else insertUsageNode.Text += $"({insertUsageNode.Nodes.Find("infoNode",true).Count()})";

            if(deleteUsageNode.Nodes.Count <= 0) deleteUsageNode.Remove();
            else deleteUsageNode.Text += $"({deleteUsageNode.Nodes.Find("infoNode",true).Count()})";

            if(unknownUsageNode.Nodes.Count <= 0) unknownUsageNode.Remove();
            else unknownUsageNode.Text += $"({unknownUsageNode.Nodes.Find("infoNode",true).Count()})";

            if(createUsageNode.Nodes.Count <= 0) createUsageNode.Remove();
            else createUsageNode.Text += $"({createUsageNode.Nodes.Find("infoNode",true).Count()})";

            #region 展开操作类型节点
            selectUsageNode.Expand();
            updateUsageNode.Expand();
            insertUsageNode.Expand();
            deleteUsageNode.Expand();
            unknownUsageNode.Expand();
            createUsageNode.Expand();
            #endregion

            this.topTreeNode.Expand();//展开顶级节点
        }


        /// <summary>
        /// 按执行时间展示树
        /// </summary>
        /// <param name="data"></param>
        private void ShowResultWithElapsedTime(Dictionary<string,List<OperateInfo>> data)
        {
            List<OperateInfo> list = data.SelectMany(it => it.Value).OrderByDescending(it => it.ElapsedTime).ToList();

            this.topTreeNode = uiTreeView_Table.Nodes.Add("topTreeNode",$"分析结果({list.Count})");

            foreach(OperateInfo operateInfo in list)
            {
                string comments = string.IsNullOrEmpty(operateInfo.Comments) ? "" : $"-{operateInfo.Comments}";
                TreeNode infoNode = this.topTreeNode.Nodes.Add("infoNode",$"位置:{operateInfo.Index}  表名:{operateInfo.TableName}{comments}  时间:{operateInfo.Timestamp}  耗时{operateInfo.ElapsedTime}",5);
                infoNode.Tag = operateInfo;
            }

            this.topTreeNode.Expand();//展开顶级节点
        }


        /// <summary>
        /// 按执行顺序展示树
        /// </summary>
        /// <param name="data"></param>
        private void ShowResultWithOrder(Dictionary<string,List<OperateInfo>> data)
        {
            List<OperateInfo> list = data.SelectMany(it => it.Value).OrderBy(it => it.Index).ToList();

            this.topTreeNode = uiTreeView_Table.Nodes.Add("topTreeNode",$"分析结果({list.Count})");

            foreach(OperateInfo operateInfo in list)
            {
                string comments = string.IsNullOrEmpty(operateInfo.Comments) ? "" : $"-{operateInfo.Comments}";
                TreeNode infoNode = this.topTreeNode.Nodes.Add("infoNode",$"位置:{operateInfo.Index}  表名:{operateInfo.TableName}{comments}  耗时{operateInfo.ElapsedTime}",5);
                infoNode.Tag = operateInfo;
            }

            this.topTreeNode.Expand();//展开顶级节点
        }


        /// <summary>
        /// 创建条目树节点
        /// </summary>
        /// <param name="key"></param>
        /// <param name="operateInfos"></param>
        /// <param name="topNode"></param>
        /// <param name="usageText"></param>
        /// <param name="imageIndex"></param>
        private void CreateInfoTreeNode(string key,IEnumerable<OperateInfo> operateInfos,TreeNode topNode,string usageText,int imageIndex)
        {
            TreeNode usageNode = topNode.Nodes.Add(key,$"{usageText}",imageIndex);

            foreach(OperateInfo item in operateInfos)
            {
                string 时间 = string.Empty;
                //if (!string.IsNullOrWhiteSpace(item.Timestamp))
                //{
                //    时间 = $"时间:{item.Timestamp}";
                //}

                string 耗时 = string.Empty;
                if(!string.IsNullOrWhiteSpace(item.ElapsedTime))
                {
                    耗时 = $"耗时:{item.ElapsedTime}";
                }

                TreeNode infoNode = usageNode.Nodes.Add("infoNode",$"位置:{item.Index} {时间} {耗时}",5);//子节点
                infoNode.Tag = item;
            }
        }


        #endregion 展示结果




        private bool firstSearch = false;//用于记录是否是搜索状态
        /// <summary>
        /// 搜索树
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtKeyword_TextChanged(object sender,EventArgs e)
        {
            if(string.IsNullOrWhiteSpace(this.txtKeyword.Text))
            {
                chbShowType_SelectedIndexChanged(sender,e);
                if(firstSearch)
                {
                    firstSearch = false;
                    treeViewHelper.SetTreeNodeState(this.topTreeNode,this.uiTreeView_Table);//恢复搜索前的树展开状态
                }
            }
            else
            {
                if(!firstSearch)
                {
                    firstSearch = true;
                    treeViewHelper = new TreeViewHelper();
                    treeViewHelper.ExecStoreNodeState(this.topTreeNode);//搜索前记录树展开状态
                }

                string keyword = this.txtKeyword.Text;

                List<OperateInfo> values = this.resultDic.SelectMany(it => it.Value).ToList();

                List<OperateInfo> resultList = new List<OperateInfo>();

                if(this.txtKeyword.TagString.Contains("表名"))
                {
                    resultList.AddRange(values.Where(it => it.TableName.ToUpper().Contains(keyword.ToUpper())));
                }
                if(this.txtKeyword.TagString.Contains("表注释"))
                {
                    resultList.AddRange(values.Where(it => it.Comments.ToUpper().Contains(keyword.ToUpper())));
                }
                if(this.txtKeyword.TagString.Contains("操作时间"))
                {
                    resultList.AddRange(values.Where(it => it.Timestamp.Contains(keyword)));
                }
                if(this.txtKeyword.TagString.Contains("Sql语句"))
                {
                    resultList.AddRange(values.Where(it => it.Sql.ToUpper().Contains(keyword.ToUpper())));
                }
                if(this.txtKeyword.TagString.Contains("字段名"))
                {
                    resultList.AddRange(values.Where(it => it.Columns.Any(jt => jt.ColumnName.ToUpper().Contains(keyword.ToUpper()))));
                }
                if(this.txtKeyword.TagString.Contains("字段注释"))
                {
                    resultList.AddRange(values.Where(it => it.Columns.Any(jt => jt.Comments.ToUpper().Contains(keyword.ToUpper()))));
                }

                resultList = resultList.Distinct().ToList();//结果去重

                Dictionary<string,List<OperateInfo>> searchDicResult = new Dictionary<string,List<OperateInfo>>();
                foreach(OperateInfo operateInfo in resultList)
                {
                    if(searchDicResult.TryGetValue(operateInfo.TableName,out List<OperateInfo> operateInfos))
                    {
                        operateInfos.Add(operateInfo);
                    }
                    else
                    {
                        searchDicResult.Add(operateInfo.TableName,new List<OperateInfo>() { operateInfo });
                    }
                }

                this.uiTreeView_Table.Nodes.Clear();
                this.codeEditorSqlResult.ClearContent();
                this.uiListBox_Column.Items.Clear();

                ShowResult(searchDicResult);
            }

        }

        /// <summary>
        /// 选择树节点事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void uiTreeView_Table_NodeMouseClick(object sender,TreeNodeMouseClickEventArgs e)
        {
            if(e.Button == MouseButtons.Left)//鼠标左键
            {

                if(e.Node.Name == "infoNode" && e.Node.Tag != null && e.Node.Tag is OperateInfo)
                {
                    OperateInfo operateInfo = e.Node.Tag as OperateInfo;
                    uiSplitContainer1.Panel2Collapsed = false;


                    uiSplitContainer3.Panel2Collapsed = operateInfo.Columns.Count <= 0;

                    this.codeEditorSqlResult.ClearContent();
                    this.codeEditorSqlResult.ContentText = operateInfo.Sql;
                    uiListBox_Column.Items.Clear();

                    foreach(DevelopTool.SqlAnalyze.Column column in operateInfo.Columns)
                    {
                        if(column.ColumnName == "*") continue;

                        if(string.IsNullOrEmpty(column.Comments))
                            uiListBox_Column.Items.Add(column.ColumnName);

                        else
                            uiListBox_Column.Items.Add(column.ColumnName + "【" + column.Comments + "】");
                    }

                    this.codeEditorSqlResult.TextPosition(operateInfo.TableName);
                }
                else
                {
                    if(!this.menuItemAlwaysShowSqlTextWindow.Checked)
                        uiSplitContainer1.Panel2Collapsed = true;

                    if(!this.menuItemAlwaysShowColumnWindow.Checked)
                        uiSplitContainer3.Panel2Collapsed = true;
                }
            }
            else if(e.Button == MouseButtons.Right)//鼠标右键
            {
                uiTreeView_Table.ContextMenuStrip = null;//绑定前先清空下右键菜单
                if(e.Node.Name == "topTreeNode" && this.resultDic.Count > 0)
                {
                    uiTreeView_Table.ContextMenuStrip = ContextMenuStripTreeView;//弹出操作菜单 
                }


            }
        }


        /// <summary>
        /// 总是显示字段窗口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void menuItemAlwaysShowColumnWindow_Click(object sender,EventArgs e)
        {
            menuItemAlwaysShowColumnWindow.Checked = !menuItemAlwaysShowColumnWindow.Checked;
            Setting.SqlAnalyze.AlwaysShowColumnWindow = menuItemAlwaysShowColumnWindow.Checked;

        }

        /// <summary>
        /// 总是显示Sql定位窗口 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void menuItemAlwaysShowSqlTextWindow_Click(object sender,EventArgs e)
        {
            menuItemAlwaysShowSqlTextWindow.Checked = !menuItemAlwaysShowSqlTextWindow.Checked;
            Setting.SqlAnalyze.AlwaysShowSqlTextWindow = menuItemAlwaysShowSqlTextWindow.Checked;
        }

        /// <summary>
        /// 数据库连接下拉框选择事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dbinfoSelectCombo_DbInfoSelected(object sender,DbinfoEventArgs e)
        {
            if(e.DbInfo == null || !e.IsConnect)
            {
                this.dbInfo = null;
                this.dbManagerBll = null;
            }
            else
            {
                this.dbInfo = e.DbInfo;
                this.dbManagerBll = new DbManagerBll(dbInfo);
            }
        }


        private void 打开文件ToolStripMenuItem_Click(object sender,EventArgs e)
        {
            string fileName = string.Empty;
            if(!Dialogs.OpenFileDialog(ref fileName)) return;
            if(string.IsNullOrWhiteSpace(fileName)) return;
            FileInfo fileInfo = new FileInfo(fileName);
            if(fileInfo == null) return;
            if(!File.Exists(fileName)) return;

            string fileContent = string.Empty;

            LoadingHelper.ShowLoading("读取文件：" + fileInfo.Name,() =>
            {
                fileContent = FileHelper.ReadFile(fileInfo.FullName);//读取文件
            });

            this.codeEditorSqlIn.ContentText = fileContent;
        }


        /// <summary>
        /// 选择树展示类型下拉框事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void chbShowType_SelectedIndexChanged(object sender,EventArgs e)
        {
            this.uiTreeView_Table.Nodes.Clear();
            this.codeEditorSqlResult.ClearContent();

            this.uiListBox_Column.Items.Clear();

            this.ShowResult(this.resultDic);
        }


        private void txtKeyword_ButtonClick(object sender,EventArgs e)
        {
            List<DataGridColumn> searchdataGridColumns = new List<DataGridColumn>()
              {
                { new DataGridColumn("SearchColumn"){ColumnText="搜素列",Width=200,ColumnType = ColumnType.DefaultFilter}},
              };

            List<string> searchColumns = new List<string>() {

            "表名","表注释","字段名","字段注释","Sql语句","操作时间"
            };


            DataTable dataTable = new DataTable("data");
            dataTable.Columns.Add("SearchColumn",typeof(string));
            foreach(string searchColumn in searchColumns)
            {
                DataRow row = dataTable.NewRow();
                row["SearchColumn"] = searchColumn;
                dataTable.Rows.Add(row);
            }


            if(this.txtKeyword.Tag == null)
            {
                this.txtKeyword.Tag = dataTable.Copy();//默认全选
            }


            DataSelectForm tableSelectForm = new DataSelectForm("选择搜素列",searchdataGridColumns,dataTable,(DataTable)this.txtKeyword.Tag);

            if(tableSelectForm.ShowDialog() == DialogResult.OK)
            {
                List<string> strings = new List<string>();
                foreach(DataRow dataRow in tableSelectForm.SelectValues.Rows)
                {
                    strings.Add(dataRow["SearchColumn"].ToString());
                }

                // this.txtKeyword.Text = string.Join(",", strings.ToArray());

                this.txtKeyword.TagString = string.Join(",",strings);
                this.txtKeyword.Tag = tableSelectForm.SelectValues;
            }

        }

        private void 导出分析结果到ExcelToolStripMenuItem_Click(object sender,EventArgs e)
        {
            DataTable dataTable = new DataTable("data");
            dataTable.Columns.Add("序号",typeof(int));
            dataTable.Columns.Add("执行时间",typeof(DateTime));
            dataTable.Columns.Add("执行耗时",typeof(decimal));
            dataTable.Columns.Add("表名",typeof(string));
            dataTable.Columns.Add("表注释",typeof(string));
            dataTable.Columns.Add("操作类型",typeof(string));
            dataTable.Columns.Add("sql语句",typeof(string));

            List<OperateInfo> list = this.resultDic.SelectMany(it => it.Value).OrderBy(it => it.Index).ToList();

            foreach(OperateInfo operateInfo in list)
            {
                if(!decimal.TryParse(operateInfo.ElapsedTime,out decimal elapsedTime)) elapsedTime = 0;

                DataRow row = dataTable.NewRow();
                row["序号"] = operateInfo.Index;
                row["执行时间"] = operateInfo.Timestamp;
                row["执行耗时"] = elapsedTime;
                row["表名"] = operateInfo.TableName;
                row["表注释"] = operateInfo.Comments;
                row["操作类型"] = operateInfo.UsageType;
                row["sql语句"] = operateInfo.Sql;
                dataTable.Rows.Add(row);
            }

            ExportHelper.ExportDataToExcel(dataTable,"Sql分析结果");
        }


        /// <summary>
        /// 点击字段，定位到文本
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void uiListBox_Column_SelectedValueChanged(object sender,EventArgs e)
        {
            if(uiListBox_Column.SelectedItem != null)
            {
                string text = uiListBox_Column.SelectedItem.ToString();
                string[] texts = text.Split("【",true);

                this.codeEditorSqlResult.TextPosition(texts[0]);
            }
        }


    }
}
